package com.cardmanager.pro.service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import cn.jh.common.utils.ChannelType;
import cn.jh.common.utils.CommonsUtil;
import com.cardmanager.pro.pojo.*;
import com.cardmanager.pro.pojo.schedule.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import com.cardmanager.pro.authorization.CreditCardManagerAuthorizationHandle;
import com.cardmanager.pro.business.ConsumeTaskPOJOBusiness;
import com.cardmanager.pro.business.RepaymentTaskPOJOBusiness;

import cn.jh.common.utils.CommonConstants;
import cn.jh.common.utils.DateUtil;

import javax.servlet.http.HttpServletRequest;

@Controller
@EnableAutoConfiguration
public class CreditCardManagerTaskService {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private RepaymentTaskPOJOBusiness repaymentTaskPOJOBusiness;

    @Autowired
    private ConsumeTaskPOJOBusiness consumeTaskPOJOBusiness;

    @Autowired
    private CreditCardManagerAuthorizationHandle creditCard;



    /**
     * 验证用户是否注册通道，进行注册并且开通，通道绑定银行卡
     * @param userId
     * @param creditCardNumber
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/creditcardmanager/verify/card/isuserable")
    public @ResponseBody Object verifyCard(@RequestParam(value = "userId") String userId,
                                           @RequestParam(value = "creditCardNumber") String creditCardNumber,
                                           @RequestParam(value = "channelId")String channelId) {
       try {
           //通道注册绑卡
           //查询通道是否绑卡
           Map params = creditCard.verifyRegister(userId,creditCardNumber,channelId,"2");
           String code = (String) params.getOrDefault("resp_code","0");
           String msg = (String) params.getOrDefault("resp_message","0");
           if(!code.equals(CommonConstants.SUCCESS)){
               if(org.apache.commons.lang.StringUtils.isNotBlank(msg)){
                   if(msg.equalsIgnoreCase(CommonConstants.PENDING)){
                       String cardId = (String) params.getOrDefault("cardNo","0");
                       params.put("cardType","1");
                       params.put(CommonConstants.RESP_CODE,CommonConstants.ERROR_FREE_QUICK_BINK);
                       params.put(CommonConstants.RESP_MESSAGE,"请输入消费银行卡短信验证");
                       params.put("cardId",cardId);
                       return params;
                   }else if(msg.equalsIgnoreCase(CommonConstants.FAIL)){
                       return CommonsUtil.returnError(CommonConstants.ERROR_FREE_QUICK_BINK_ERROR,CommonConstants.ERROR_FREE_QUICK_BINK_ERROR_MSG);
                   }else if(!msg.equalsIgnoreCase(CommonConstants.BASE_SUCCESS)){
                       boolean fle = CommonsUtil.verifyError(code);
                       if(fle){
                           return CommonsUtil.returnSuccess("可进入生成还款计划!");
                       }
                   }
               }
               boolean fle = CommonsUtil.verifyError(code);
               if(!fle){
                   if (CommonConstants.FALIED.equals(code)) {
                       return CommonsUtil.returnError(code, msg);
                   }
                   return CommonsUtil.returnError(code,CommonsUtil.freeQuickError(code));
               }
           }
           log.info("CreditCardManagerTaskService.verifyCardIsUseable, 可进入生成还款计划 " + userId);
           return CommonsUtil.returnSuccess("可进入生成还款计划！");
       }catch (Exception e){
           log.error("CreditCardManagerTaskService.verifyCard,预约还款异常======" + e.getMessage());
//            return CommonsUtil.returnError("生成还款计划失败！" + e.getMessage());
           e.printStackTrace();
            return CommonsUtil.returnError("生成还款计划失败！");
       }
    }


    /**
     * 生成展示的临时任务
     * @param task
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = {"/v1.0/creditcardmanager/task/temporary"})
    public @ResponseBody  Object taskTemporary(HttpServletRequest request, CreditTask task){
        String suserId = task.getSuserId();

        String expiredTime = task.getExecuteDate();//执行计划时间
        BigDecimal useQuota = task.getUseQuota();//已使用额度
        String statementDate = task.getStatementDate();//信用卡账单日
        String repaymentDate = task.getRepaymentDate();//信用卡还款日

//        String[] splitDate = expiredTime.split(",");//自选还款日
//        int size =  splitDate.length;//自选还款日天数

        String ip = "";
        if (task.getChannelId().equals("5")) {
            ip = request.getRemoteAddr();
        }

        try {
            DateFormat dff = new SimpleDateFormat("yyyy-MM-dd");
            String nowTime = dff.format(new Date());
            nowTime = nowTime.substring(0,nowTime.length()-2);
            Date statement = dff.parse(nowTime+statementDate);
            Date repayment = dff.parse(nowTime+repaymentDate);

            //如果还款日小于账单日
            if(Integer.parseInt(repaymentDate)<Integer.parseInt(statementDate) || Integer.parseInt(repaymentDate)-Integer.parseInt(statementDate)<15){
                Calendar cal = Calendar.getInstance();
                cal.setTime(repayment);//设置起时间
                cal.add(Calendar.MONTH, 1);//增加一个月
                repayment = cal.getTime();
            }

            //验证是否有批量生成的未执行计划 消费
            //代还
            List<RepaymentTaskPOJO> list = consumeTaskPOJOBusiness.queryRepaymentTask(suserId, task.getBankCardNumber());
            if (list.size() > 0) {
                return CommonsUtil.returnError(CommonConstants.FALIED, "您有未执行计划,请等待任务执行完后再生成计划!");
            }
            //验证日期格式是否正确
            Date executeDates;
            try {
                executeDates = DateUtil.getDateStringConvert(new Date(), expiredTime, "yyyy-MM-dd");
            } catch (Exception e) {
                return CommonsUtil.returnError(CommonConstants.FALIED, "生成计划失败,原因:选择日期格式有误,正确格式为:2000-01-01");
            }

            Date dateNow = DateUtil.getDateStringConvert(new Date(), DateUtil.getDateStringConvert(new String(), new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");
            dateNow = new Date(dateNow.getTime() + 24 * 60 * 60 * 1000);
            //验证日期是否是今天以后
            if (dateNow.getTime() > executeDates.getTime()) {
                return com.cardmanager.pro.util.CommonsUtil.returnError(CommonConstants.FALIED,"只能选择今天以后的日期,请重新选择!");
            }
            //账单日/还款日不小于0,
//            if (statement.getTime() > repayment.getTime()) {
//                return CommonsUtil.returnError(CommonConstants.FALIED, "账单日期不可以大于还款日期,请在该日期之间进行选择");
//            }
            //执行日期不可以小于账单日期并且不可以大于还款日期
            if(executeDates.getTime() < statement.getTime()){
                return CommonsUtil.returnError(CommonConstants.FALIED, "执行还款日期不可以小于账单日期,请核实!");
            }
            if(executeDates.getTime() > repayment.getTime()){
                return CommonsUtil.returnError(CommonConstants.FALIED, "执行还款日期不可以大于还款日期,请核实!");
            }

            //查询银行卡信息和个人费率信息
            Map map = creditCard.verifyBankInfo(task.getBankCardNumber(), Integer.valueOf(suserId), "1", task.getChannelId());
            Map results = (Map) map.get("result");
            //查询费率
            Map pram = (Map) results.get("channelRate");
            //查询费率
            double rate = 0.0;
            int extraFee = 0;
            if(!pram.isEmpty()){
                rate = (double) pram.getOrDefault("rate","0");//代还/提现单笔交易手续费
                //int fee =
                extraFee = (Integer) pram.getOrDefault("extraFee","0");//交易用户费率
            }
            String executeDate = task.getExecuteDate();
            LocalDate beginDateTime = LocalDate.parse(executeDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

            String channelTag = ChannelType.of(Integer.valueOf(task.getChannelId())).getValue();//通道名称

            //每笔金额必须大于100 小于2000
            RepaymentSchedules ps = new RepaymentSchedules(Long.valueOf(suserId));
            ps.setSingleCc(new BigDecimal(extraFee));//单笔交易手续费。
            ps.setSinglePmtRate(new BigDecimal(rate));//单笔交易费率
            ps.setTotalAmount(useQuota);
            Instant instant = statement.toInstant();
            ZoneId billDate = ZoneId.systemDefault();
            Instant repaymentIn = repayment.toInstant();
            // atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
            LocalDate localDate = instant.atZone(billDate).toLocalDate();
            LocalDate repaymentLo = repaymentIn.atZone(billDate).toLocalDate();
            ps.setBillDate(localDate);//帐单日
            ps.setRepaymentDate(repaymentLo);//还款日
            ps.setExecuteDate(beginDateTime);

            RepaymentSchedule schedule = ps.schedule();

            int numbers = schedule.getSchedules().size();
            LocalDate execute = LocalDate.of(beginDateTime.getYear(),beginDateTime.getMonth(),beginDateTime.getDayOfMonth());
            //用户设置执行天数,还款日减去执行日
            long day = repaymentLo.toEpochDay() - execute.toEpochDay();
            //判断任务执行所需天数和用户设置执行天数是否大等于
            if(numbers > day){
                return CommonsUtil.returnError(CommonConstants.FALIED, "还款金额拆分天数不能大于执行日期和还款日期最大数,请核实!");
            }
            RepaymentTaskPOJO pojo = new RepaymentTaskPOJO();
            pojo.setUserId(task.getSuserId());
            pojo.setOrderStatus(0);
            pojo.setCreditCardNumber(task.getBankCardNumber());
            pojo.setRepaymentTaskId(String.valueOf(System.currentTimeMillis()));
            if (task.getChannelId().equals("5")) {
                pojo.setClientIp(ip);
                pojo.setArea(task.getArea());
            }
            pojo.setExecuteDate(task.getExecuteDate());
            pojo.setExecuteDateTime(expiredTime);
            pojo.setRealAmount(task.getUseQuota());
            String orderNo = CommonsUtil.getNumberOrderCode();
            pojo.setOrderNo(orderNo);
            pojo.setChannelId(task.getChannelId());
            pojo.setRate(new BigDecimal(rate));//手续费
            pojo.setChannelTag(channelTag);
            BigDecimal actualDc = BigDecimal.ZERO, actualDtf = BigDecimal.ZERO;
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //每天执行计划
            for (ScheduleItem skd : schedule.getSchedules()) {
                //总手续费，总费率+手续费，执行计划总金额；
                BigDecimal ac = BigDecimal.ZERO;
                //子计划
                for (ItemPart itemPart : skd.getItemParts()) {
                    RepaymentTaskPOJO poj = new RepaymentTaskPOJO();
                    poj.setUserId(task.getSuserId());
                    poj.setOrderStatus(0);
                    poj.setCreditCardNumber(task.getBankCardNumber());
                    poj.setRepaymentTaskId(String.valueOf(System.currentTimeMillis()));
                    poj.setExecuteDate(task.getExecuteDate());
                    poj.setRealAmount(task.getUseQuota());
                    poj.setChannelId(task.getChannelId());
                    poj.setChannelTag(channelTag);
                    poj.setOrderNo(orderNo);
                    pojo.setTaskStatus(3);
                    if (task.getChannelId().equals("5")) {
                        poj.setClientIp(ip);
                        poj.setArea(task.getArea());
                    }
                    poj.setPlanType("1");
                    String localTime = df.format(itemPart.getDateTime());
                    DateTimeFormatter dfs = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    String executeDatess = dfs.format(itemPart.getDateTime());
                    pojo.setExecuteDate(executeDatess);
                    poj.setExecuteDateTime(localTime);
                    if (itemPart.getAction() != ItemAction.REPAYMENT) {
                        BigDecimal actual = new BigDecimal(extraFee);//交易手续费
                        BigDecimal avg = actual.add(itemPart.getTradingFee());//单次总手续费+费率
                        BigDecimal amount = itemPart.getAmount().add(avg);
                        poj.setAmount(amount);
                        poj.setTotalServiceCharge(avg);
                        poj.setRate(new BigDecimal(rate));
                        poj.setServiceCharge(new BigDecimal(extraFee));
                        actualDtf = actualDtf.add(avg);
                        actualDc = actualDc.add(actual);
                        ac = ac.add(amount);
                        poj.setTaskType(1);

                    }else{
                        poj.setTaskType(2);
                        poj.setAmount(ac);
                        poj.setTotalServiceCharge(new BigDecimal(0.00));
                        poj.setServiceCharge(new BigDecimal(0.00));
                    }
                    repaymentTaskPOJOBusiness.save(poj);
                }
            }
            pojo.setRepaymentTaskId(String.valueOf(System.currentTimeMillis()));
            pojo.setPlanType("2");
            pojo.setTaskStatus(5);
            pojo.setTaskType(3);
            BigDecimal ac = useQuota.add(actualDtf);
            pojo.setAmount(ac);
            pojo.setServiceCharge(actualDc);
            pojo.setTotalServiceCharge(actualDtf);
            //保存父计划
            repaymentTaskPOJOBusiness.save(pojo);
            return CommonsUtil.returnSuccess("生成临时计划成功！");
        }catch (Exception e){
            log.error("CreditCardManagerTaskService.taskTemporary,生成临时计划,userId======" + task.getSuserId() + ", 异常====="+e.getMessage());
            e.printStackTrace();
            return CommonsUtil.returnError("生成临时计划失败！");
        }
    }

    /**
     * 更新执行任务状态
     * @param userId
     * @param creditCardNumber
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/creditcardmanager/update/all/plan")
    public @ResponseBody Object saveRepaymentTaskAndConsumeTask(String userId,String creditCardNumber,String type) {
        try {
            //查询是否有待执行计划
            List<RepaymentTaskPOJO> list = consumeTaskPOJOBusiness.queryRepaymentTask(userId, creditCardNumber);
            if (list.size() < 1) {
                return CommonsUtil.returnError(CommonConstants.FALIED, "您没有可以执行的计划,请生成计划!");
            }
            if(type.equals("2")){
                consumeTaskPOJOBusiness.deleteRepaymentTask(list);
                return com.cardmanager.pro.util.CommonsUtil.returnSuccess("删除计划成功!");
            }else{
                consumeTaskPOJOBusiness.updateRepaymentTask(userId, creditCardNumber);
                return com.cardmanager.pro.util.CommonsUtil.returnSuccess("激活计划成功!");
            }

        } catch (Exception e) {
            log.error("CreditCardManagerTaskService.saveRepaymentTaskAndConsumeTask，保存计划userId======" + userId + "异常=========" + e);
            return com.cardmanager.pro.util.CommonsUtil.returnError(CommonConstants.FALIED, "保存计划失败,原因:服务器正忙,请稍后重试!");
        }
    }

}
